package ch9;

import util.Debug;
import util.Tools;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.*;

public class FileBatchUploader implements Closeable {
    private final CompletionService<File> completionService;
    private final ExecutorService es;
    private final ExecutorService dispatcher;

    public FileBatchUploader(String ftpServer, String userName, String password, String targetRemoteDir) {
        this.es = Executors.newSingleThreadExecutor();
        this.dispatcher = Executors.newSingleThreadExecutor();
        this.completionService = new ExecutorCompletionService<File>(es);
    }

    public void uploadFiles(final Set<File> files) {
        dispatcher.submit(new Runnable() {
            @Override
            public void run() {
                doUploadFiles(files);
            }
        });
    }

    private void doUploadFiles(Set<File> files) {
    }

    private void diUploadFiles(Set<File> files) throws InterruptedException {
        // 批量提交文件上传任务
        for (final File file : files) {
            completionService.submit(new UploadTask(file));
        }
        Future<File> future;
        File md5File;
        File uploadedFile;
        Set<File> md5Files = new HashSet<File>();

        for (File file : files) {
            try {
                future = completionService.take();
                uploadedFile = future.get();
                // 将上传成功的文件移动到备份目录，并为其生成相应的MD5文件
                md5File = generateMD5(moveToSuccessDir(uploadedFile));
                md5Files.add(md5File);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
                moveToDeadDir(file);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        for (File file : md5Files) {
            //上传相应的MD5文件
            completionService.submit(new UploadTask(file));
        }

        // 检查MD5文件的上传结果
        int successUploaded = md5Files.size();
        for (int i = 0; i < successUploaded; i++) {
            future = completionService.take();
            try {
                uploadedFile = future.get();
                md5Files.remove(uploadedFile);
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }

        // 将剩余（上传未成功的）的MD5文件移动到相应的备份目录
        for (File file : md5Files) {
            moveToDeadDir(file);
        }
    }

    private File moveToSuccessDir(File uploadedFile) {
        return null;
    }

    private File generateMD5(File file) throws IOException, NoSuchAlgorithmException {
        String md5 = Tools.md5sum(file);
        File md5File = new File(file.getAbsolutePath() + ".md5");
        Files.write(Paths.get(md5File.getAbsolutePath()), md5.getBytes("UTF-8"));
        return md5File;
    }

    private static File moveTOsuccessDir(File file) throws IOException {
        File targetFile = null;
        targetFile = moveFile(file, Paths.get(file.getParent(), "..", "backup", "success"));
        return targetFile;
    }

    private static File moveToDeadDir(File file) {
        File targetFile = null;
        targetFile = moveFile(file, Paths.get(file.getParent(), "..", "backup", "dead"));
        return targetFile;
    }

    private static File moveFile(File srcFIle, Path destPath) {
        return null;
    }

    class UploadTask implements Callable<File> {
        private final File file;

        public UploadTask(File file) {
            this.file = file;
        }

        @Override
        public File call() throws Exception {
           Debug.info("uploading %s", file.getCanonicalPath());
           // 上传指定文件
            upload(file);
            return file;
        }
    }

    // 初始化FTP客户端
    public void init() {
        //
    }

    // 将指定的文件上传至FTP服务器
    protected void upload(File file) {
        //
    }

    @Override
    public void close() throws IOException {

    }
}
